package cn.h8k.hj212.plugin;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 插件管理器
 * 负责管理所有监测因子插件的生命周期
 * 
 * @author HJ212 Team
 * @since 1.0
 */
public class PluginManager {
    
    private static final Logger logger = LoggerFactory.getLogger(PluginManager.class);
    
    private static volatile PluginManager instance;
    
    private final Map<String, MonitoringFactorPlugin> plugins = new ConcurrentHashMap<>();
    private final Map<String, List<MonitoringFactorPlugin>> factorCodeToPlugins = new ConcurrentHashMap<>();
    private final Map<String, List<MonitoringFactorPlugin>> systemTypeToPlugins = new ConcurrentHashMap<>();
    private final List<PluginLifecycleListener> listeners = new CopyOnWriteArrayList<>();
    
    private PluginManager() {
        // 私有构造函数，实现单例模式
    }
    
    /**
     * 获取插件管理器实例
     * @return 插件管理器实例
     */
    public static PluginManager getInstance() {
        if (instance == null) {
            synchronized (PluginManager.class) {
                if (instance == null) {
                    instance = new PluginManager();
                }
            }
        }
        return instance;
    }
    
    /**
     * 注册插件
     * @param plugin 监测因子插件
     */
    public void registerPlugin(MonitoringFactorPlugin plugin) {
        if (plugin == null) {
            throw new IllegalArgumentException("插件不能为空");
        }
        
        String pluginName = plugin.getName();
        if (pluginName == null || pluginName.trim().isEmpty()) {
            throw new IllegalArgumentException("插件名称不能为空");
        }
        
        logger.info("注册插件: {} v{}", pluginName, plugin.getVersion());
        
        // 检查是否已存在同名插件
        if (plugins.containsKey(pluginName)) {
            logger.warn("插件 {} 已存在，将被替换", pluginName);
            unregisterPlugin(pluginName);
        }
        
        try {
            // 初始化插件
            plugin.initialize(new HashMap<>());
            
            // 注册插件
            plugins.put(pluginName, plugin);
            
            // 建立监测因子代码到插件的映射
            for (String factorCode : plugin.getSupportedFactorCodes()) {
                factorCodeToPlugins.computeIfAbsent(factorCode, k -> new ArrayList<>()).add(plugin);
            }
            
            // 建立系统类型到插件的映射
            for (String systemType : plugin.getSupportedSystemTypes()) {
                systemTypeToPlugins.computeIfAbsent(systemType, k -> new ArrayList<>()).add(plugin);
            }
            
            // 通知监听器
            notifyPluginRegistered(plugin);
            
            logger.info("插件 {} 注册成功", pluginName);
            
        } catch (Exception e) {
            logger.error("插件 {} 注册失败", pluginName, e);
            throw new RuntimeException("插件注册失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 注销插件
     * @param pluginName 插件名称
     */
    public void unregisterPlugin(String pluginName) {
        MonitoringFactorPlugin plugin = plugins.remove(pluginName);
        if (plugin != null) {
            logger.info("注销插件: {}", pluginName);
            
            try {
                // 清理映射关系
                cleanupPluginMappings(plugin);
                
                // 销毁插件资源
                plugin.destroy();
                
                // 通知监听器
                notifyPluginUnregistered(plugin);
                
                logger.info("插件 {} 注销成功", pluginName);
                
            } catch (Exception e) {
                logger.error("插件 {} 注销失败", pluginName, e);
            }
        }
    }
    
    /**
     * 获取支持指定监测因子的插件列表
     * @param factorCode 监测因子代码
     * @return 插件列表
     */
    public List<MonitoringFactorPlugin> getPluginsForFactor(String factorCode) {
        return factorCodeToPlugins.getOrDefault(factorCode, Collections.emptyList());
    }
    
    /**
     * 获取支持指定系统类型的插件列表
     * @param systemType 系统类型
     * @return 插件列表
     */
    public List<MonitoringFactorPlugin> getPluginsForSystemType(String systemType) {
        return systemTypeToPlugins.getOrDefault(systemType, Collections.emptyList());
    }
    
    /**
     * 获取所有已注册的插件
     * @return 插件映射
     */
    public Map<String, MonitoringFactorPlugin> getAllPlugins() {
        return new HashMap<>(plugins);
    }
    
    /**
     * 验证监测因子数据
     * @param factorCode 监测因子代码
     * @param value 监测值
     * @param flag 数据标识
     * @return 验证结果
     */
    public MonitoringFactorPlugin.ValidationResult validateFactor(String factorCode, Object value, String flag) {
        List<MonitoringFactorPlugin> supportedPlugins = getPluginsForFactor(factorCode);
        
        if (supportedPlugins.isEmpty()) {
            logger.debug("未找到支持监测因子 {} 的插件", factorCode);
            return MonitoringFactorPlugin.ValidationResult.success(); // 默认通过
        }
        
        // 使用第一个支持的插件进行验证
        MonitoringFactorPlugin plugin = supportedPlugins.get(0);
        try {
            return plugin.validateFactor(factorCode, value, flag);
        } catch (Exception e) {
            logger.error("验证监测因子 {} 时发生错误", factorCode, e);
            return MonitoringFactorPlugin.ValidationResult.failure("验证失败: " + e.getMessage(), "VALIDATION_ERROR");
        }
    }
    
    /**
     * 添加插件生命周期监听器
     * @param listener 监听器
     */
    public void addPluginLifecycleListener(PluginLifecycleListener listener) {
        if (listener != null) {
            listeners.add(listener);
        }
    }
    
    /**
     * 移除插件生命周期监听器
     * @param listener 监听器
     */
    public void removePluginLifecycleListener(PluginLifecycleListener listener) {
        listeners.remove(listener);
    }
    
    /**
     * 清理插件映射关系
     * @param plugin 插件
     */
    private void cleanupPluginMappings(MonitoringFactorPlugin plugin) {
        // 清理监测因子代码映射
        for (String factorCode : plugin.getSupportedFactorCodes()) {
            List<MonitoringFactorPlugin> pluginList = factorCodeToPlugins.get(factorCode);
            if (pluginList != null) {
                pluginList.remove(plugin);
                if (pluginList.isEmpty()) {
                    factorCodeToPlugins.remove(factorCode);
                }
            }
        }
        
        // 清理系统类型映射
        for (String systemType : plugin.getSupportedSystemTypes()) {
            List<MonitoringFactorPlugin> pluginList = systemTypeToPlugins.get(systemType);
            if (pluginList != null) {
                pluginList.remove(plugin);
                if (pluginList.isEmpty()) {
                    systemTypeToPlugins.remove(systemType);
                }
            }
        }
    }
    
    /**
     * 通知插件注册事件
     * @param plugin 插件
     */
    private void notifyPluginRegistered(MonitoringFactorPlugin plugin) {
        for (PluginLifecycleListener listener : listeners) {
            try {
                listener.onPluginRegistered(plugin);
            } catch (Exception e) {
                logger.error("通知插件注册事件时发生错误", e);
            }
        }
    }
    
    /**
     * 通知插件注销事件
     * @param plugin 插件
     */
    private void notifyPluginUnregistered(MonitoringFactorPlugin plugin) {
        for (PluginLifecycleListener listener : listeners) {
            try {
                listener.onPluginUnregistered(plugin);
            } catch (Exception e) {
                logger.error("通知插件注销事件时发生错误", e);
            }
        }
    }
    
    /**
     * 插件生命周期监听器接口
     */
    public interface PluginLifecycleListener {
        
        /**
         * 插件注册时调用
         * @param plugin 插件
         */
        void onPluginRegistered(MonitoringFactorPlugin plugin);
        
        /**
         * 插件注销时调用
         * @param plugin 插件
         */
        void onPluginUnregistered(MonitoringFactorPlugin plugin);
    }
}
